/* 可辩别联合 */

// 使用了一个联合类型，"circle" | "square" ，
// 使用这种方式，而不是一个 string，我们可以避免一些拼写错误
interface Shape {
  kind: "circle" | "square";
  radius?: number;
  sideLength?: number;
}

function handleShape(shape: Shape) {
  // oops!
  if (shape.kind === "rect") {
	// This comparison appears to be unintentional because the types '"circle" | "square"' and '"rect"' have no overlap.ts(2367)
  // ...
  }
}

function getArea(shape: Shape) {
  return Math.PI * shape.radius ** 2; // 圆的面积公式 S=πr²
  // Object is possibly 'undefined'.
}

function getArea1(shape: Shape) {
  if (shape.kind === "circle") {
    return Math.PI * shape.radius ** 2;
		// Object is possibly 'undefined'.
  }
}

function getArea2(shape: Shape) {
  if (shape.kind === "circle") {
    // 使用非空断言
    return Math.PI * shape.radius! ** 2;
		// Object is possibly 'undefined'.
  }
}

// 当联合类型中的每个类型，都包含了一个共同的字面量类型的属性，
// TypeScript 就会认为这是一个可辨别联合（discriminated union），然后可以将具体成员的类型进行收窄。
interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape1 = Circle | Square;

function getArea3(shape: Shape1) {
  return Math.PI * shape.radius ** 2;
}

function getArea4(shape: Shape1) {
  if (shape.kind === "circle") {
    // 使用非空断言
    return Math.PI * shape.radius ** 2;
		// Object is possibly 'undefined'.
  }
}